延續昨天的話題,看到 <<
一般來說都會先想到 push
這個方法。
array = [1, 2, 3]
array << 4
array # 印出 [1, 2, 3, 4]
不過我們今天要討論的其實是 class method
,先來複習一下我們最熟悉的兩種寫法:
class Language
def self.introduction
"no pain no gain"
end
end
class Language
class << self
def introduction
"no pain no gain"
end
end
end
在經過對 singleton method
的了解後,應該已經知道其實方法寫在哪裡並不是重點,因為他們其實都被儲存在 singleton class
裡,你可以試試看以下程式碼:
#1
class Language
def self.introduction
"no pain no gain"
end
end
#2
class Language
def Language.introduction
"no pain no gain"
end
end
#3
class Language
end
def Language.introduction
"no pain no gain"
end
又或是你學到的是以下這種方法:
#1
class Language
class << self
def introduction
"no pain no gain"
end
end
end
#2
class Language
class << Language
def introduction
"no pain no gain"
end
end
end
#3
class Language
end
class << Language
def introduction
"no pain no gain"
end
end
如果看了前面兩種寫法,現在你已經知道共通點,或許你會想到我們昨天說的惡搞,其實就只是:「啊!你沒有名字呀?那我幫你取個名就能把你用開放類別玩囉!」你可以想像 class << Language
這個寫法其實就在做這樣的事:
class Language
end
Metaclass = Language.singleton_class
class Metaclass
def introduction
"no pain no gain"
end
end
原來 <<
可以在不另外幫 singleton class 取名的情況下叫出 singleton class ,就如同 each
方法有 map
、 select
、 reduce
這些衍生的方法來為我們節省時間一樣, Ruby 其實早就幫我們想了一個簡單的方法來操作 singleton class 了。
class Language
def say_hello
"hello world"
end
end
ruby = Language.new
python = Language.new
class << ruby
def on
"rails"
end
end
ruby.on # 印出 rails
python.on # 印出 undefined method `on' for...
所以未來不要再因為看到 self
或 <<
就覺得是類別方法,也不用糾結這是實體方法還是類別分法(畢竟 class 也是 Class 的實體呀!),你可以想成方法只被分為 其他人可以一起用的
或者 自己獨享的
兩種而已。
此文同步刊登於CJ-Han的網站